<!DOCTYPE html>
<html lang="zh-CN">
  <head>
  <meta charset="UTF-8">
  <meta 
    name="viewport"
    content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <meta 
    http-equiv="X-UA-Compatible" 
    content="ie=edge">
  <meta 
    name="theme-color" 
    content="#fff" 
    id="theme-color">
  <meta 
    name="description" 
    content="Gas">
  <link 
    rel="icon" 
    href="/img/Kaze.png">
  <title>Spring</title>
  
    
      <meta 
        property="og:title" 
        content="Spring">
    
    
      <meta 
        property="og:url" 
        content="http://example.com/2021/03/28/Spring/index.html">
    
    
      <meta 
        property="og:img" 
        content="/img/Kaze.png">
    
    
    
      <meta 
        property="og:type" 
        content="article">
      <meta 
        property="og:article:published_time" 
        content="2021-03-28">
      <meta 
        property="og:article:modified_time" 
        content="2021-04-27">
      <meta 
        property="og:article:author" 
        content="Gas">
      
        
          <meta 
            property="og:article:tag" 
            content="Spring">
        
          <meta 
            property="og:article:tag" 
            content="AOP">
        
          <meta 
            property="og:article:tag" 
            content="IOC">
        
      
    
  
  <script>
    function loadScript(url, cb) {
      var script = document.createElement('script');
      script.src = url;
      if (cb) script.onload = cb;
      script.async = true;
      document.body.appendChild(script);
    }
    function loadCSS(href, data, attr) {
      var sheet = document.createElement('link');
      sheet.ref = 'stylesheet';
      sheet.href = href;
      sheet.dataset[data] = attr;
      document.head.appendChild(sheet);
    }
    function changeCSS(cssFile, data, attr) {
      var oldlink = document.querySelector(data);
      var newlink = document.createElement("link");
      newlink.setAttribute("rel", "stylesheet");
      newlink.setAttribute("href", cssFile);
      newlink.dataset.prism = attr;
      document.head.replaceChild(newlink, oldlink);
    }
  </script>
  
    
      
      
      
      
        
        
        
        <script>
          function prismThemeChange() {
            if(document.getElementById('theme-color').dataset.mode === 'dark') {
              if(document.querySelector('[data-prism]')) {
                changeCSS('/js/lib/prism/prism-tomorrow.min.css', '[data-prism]', 'prism-tomorrow');
              } else {
                loadCSS('/js/lib/prism/prism-tomorrow.min.css', 'prism', 'prism-tomorrow');
              }
            } else {
              if(document.querySelector('[data-prism]')) {
                changeCSS('/js/lib/prism/prism-okaidia.min.css', '[data-prism]', 'prism-okaidia');
              } else {
                loadCSS('/js/lib/prism/prism-okaidia.min.css', 'prism', 'prism-okaidia');
              }
            }
          }
          prismThemeChange()
        </script>
      
      
        
        <link rel="stylesheet" href="/js/lib/prism/prism-line-numbers.min.css">
      
    
  
  <script>
    // control reverse button
    var reverseDarkList = {
      dark: 'light',
      light: 'dark'
    };
    var themeColor = {
      dark: '#1c1c1e',
      light: '#fff'
    }
    // get the data of css prefers-color-scheme
    var getCssMediaQuery = function() {
      return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    };
    // reverse current darkmode setting function
    var reverseDarkModeSetting = function() {
      var setting = localStorage.getItem('user-color-scheme');
      if(reverseDarkList[setting]) {
        setting = reverseDarkList[setting];
      } else if(setting === null) {
        setting = reverseDarkList[getCssMediaQuery()];
      } else {
        return;
      }
      localStorage.setItem('user-color-scheme', setting);
      return setting;
    };
    // apply current darkmode setting
  </script>
  
    <script>
      var setDarkmode = function(mode) {
      var setting = mode || localStorage.getItem('user-color-scheme');
      if(setting === getCssMediaQuery()) {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[setting];
        document.getElementById('theme-color').dataset.mode = setting;
        prismThemeChange();
      } else if(reverseDarkList[setting]) {
        document.documentElement.setAttribute('data-user-color-scheme', setting);
        document.getElementById('theme-color').content = themeColor[setting];
        document.getElementById('theme-color').dataset.mode = setting;
        prismThemeChange();
      } else {
        document.documentElement.removeAttribute('data-user-color-scheme');
        localStorage.removeItem('user-color-scheme');
        document.getElementById('theme-color').content = themeColor[getCssMediaQuery()];
        document.getElementById('theme-color').dataset.mode = getCssMediaQuery();
        prismThemeChange();
      }
    };
    setDarkmode();
    </script>
  
  
  <link rel="preload" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css" as="style" >
  <link rel="preload" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css" as="style" >
  
  
    <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.js" as="script">
    <link rel="preload" href="/js/lib/lightbox/baguetteBox.min.css" as="style" >
  
  
    <link rel="preload" href="/js/lib/lozad.min.js" as="script">
  
  
  
  
  
  
  
  <link rel="stylesheet" href="/css/main.css">
  
  <link rel="stylesheet" href="//at.alicdn.com/t/font_1946621_i1kgafibvw.css">
  
  <link rel="stylesheet" href="//at.alicdn.com/t/font_1952792_89b4ac4k4up.css">
  <link rel="stylesheet" href="//at.alicdn.com/t/font_2818401_duebq0kmk47.css">
  
    <link rel="stylesheet" href="/js/lib/lightbox/baguetteBox.min.css">
  
<meta name="generator" content="Hexo 5.4.0"></head>

  <body>
    <div class="wrapper">
       
      <nav class="navbar">
  <div class="navbar-logo">
    <span class="navbar-logo-main">
      
        <img 
          class="navbar-logo-img" 
          src="/img/Kaze.png" 
          alt="blog logo">
      
      <span class="navbar-logo-dsc">Gas</span>
    </span>
  </div>
  <div class="navbar-menu">
    
      <a 
        href="/" 
        class="navbar-menu-item">
        
          首页
        
      </a>
    
      <a 
        href="/archives" 
        class="navbar-menu-item">
        
          归档
        
      </a>
    
      <a 
        href="/tags" 
        class="navbar-menu-item">
        
          标签
        
      </a>
    
      <a 
        href="/categories" 
        class="navbar-menu-item">
        
          分类
        
      </a>
    
      <a 
        href="/about" 
        class="navbar-menu-item">
        
          关于
        
      </a>
    
      <a 
        href="/links" 
        class="navbar-menu-item">
        
          友链
        
      </a>
    
    <a 
      class="navbar-menu-item darknavbar" 
      id="dark">
      <i class="iconfont icon-weather"></i>
    </a>
    <a 
      class="navbar-menu-item searchnavbar" 
      id="search">
      <i 
        class="iconfont icon-search" 
        style="font-size: 1.2rem; font-weight: 400;">
      </i>
    </a>
  </div>
</nav> 
      
      <div 
        id="local-search" 
        style="display: none">
        <input
          class="navbar-menu-item"
          id="search-input"
          placeholder="请输入搜索内容..." />
        <div id="search-content"></div>
      </div>
      
      <div class="section-wrap">
        <div class="container">
          <div class="columns">
            <main class="main-column">
<article class="card card-content">
  <header>
    <h1 class="post-title">
      Spring
    </h1>
  </header>
  <div class="post-meta post-show-meta">
    <time datetime="2021-03-28T11:28:39.000Z">
      <i 
        class="iconfont icon-calendar" 
        style="margin-right: 2px;">
      </i>
      <span>2021-03-28</span>
    </time>
    
      <span class="dot"></span>
      
        <a 
          href="/categories/Spring/" 
          class="post-meta-link">
          Spring
        </a>
      
    
    
      <span class="dot"></span>
      <span>6.3k 字</span>
    
  </div>
  
    <div 
      class="post-meta post-show-meta" 
      style="margin-top: -10px;">
      <div style="display: flex; align-items: center;">
        <i 
          class="iconfont icon-biaoqian" 
          style="margin-right: 2px; font-size: 1.15rem;">
        </i>
        
          
          <a 
            href="/tags/Spring/" 
            class="post-meta-link">
            Spring
          </a>
        
          
            <span class="dot"></span>
          
          <a 
            href="/tags/AOP/" 
            class="post-meta-link">
            AOP
          </a>
        
          
            <span class="dot"></span>
          
          <a 
            href="/tags/IOC/" 
            class="post-meta-link">
            IOC
          </a>
        
      </div>
    </div>
  
  </header>
  <div 
    id="section" 
    class="post-content">
    <h2 id="1、Spring"><a href="#1、Spring" class="headerlink" title="1、Spring"></a>1、Spring</h2><h3 id="1-2、优点"><a href="#1-2、优点" class="headerlink" title="1.2、优点"></a>1.2、优点</h3><ul>
<li>Spring 是一个开源的免费框架（容器）</li>
<li>Spring 是一个轻量级的、非入侵式的框架！</li>
<li>控制反转（IOC），面向切面编程（AOP）</li>
<li>支持事务的处理，对框架整合的支持</li>
</ul>
<p><strong>总结一句话：Spring 是一个轻量级的控制反转和面向切面编程的框架</strong></p>
<h3 id="1-3、组成"><a href="#1-3、组成" class="headerlink" title="1.3、组成"></a>1.3、组成</h3><p><img  srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/Spring_01.png" class="lozad post-image"src="/2021/03/28/Spring/Spring_01.png"></p>
<h3 id="1-4、拓展"><a href="#1-4、拓展" class="headerlink" title="1.4、拓展"></a>1.4、拓展</h3><ul>
<li>SpringBoot<ul>
<li>一个快速开发的脚手架</li>
<li>基于 SpringBoot 可以快速的开发单个微服务</li>
<li>约定大于配置！</li>
</ul>
</li>
<li>Spring Cloud<ul>
<li>SpringCloud 是基于 SpringBoot 实现的</li>
</ul>
</li>
</ul>
<p>现在大多数公司都在使用 SpringBoot 进行快速开发，学习 SpringBoot 的前提，需要完全掌握 Spring 及 SpringMVC！承上启下</p>
<h2 id="2、IOC-理论推导"><a href="#2、IOC-理论推导" class="headerlink" title="2、IOC 理论推导"></a>2、IOC 理论推导</h2><ol>
<li>UserDao 接口</li>
<li>UserDaoImpl 实现类</li>
<li>UserService 业务接口</li>
<li>UserServiceImpl 业务实现类</li>
</ol>
<p>在我们之前的业务中，用户的需求可能会影响我们原来的代码，我们需要根据用户的需求去修改原代码！如果程序代码量十分大，修改一次的成本代价十分昂贵！</p>
<p>我们使用一个 Set 接口实现:</p>
<pre><code class="java">private UserDao userDao; //利用set进行动态实现值的注入！

public void setUserDao(UserDao userDao)
&#123;
    this.userDao=userDao;
&#125;
</code></pre>
<ul>
<li>之前，程序是主动创建对象！控制权在程序员手上</li>
<li>使用 set 之后，程序不在具有主动性，而是被动的接受对象（对扩展开发，对修改关闭）</li>
</ul>
<p>从本质上解决问题，不需要管理对象的创建，耦合性降低，专注于业务实现，这就是 IOC 的原型。</p>
<h3 id="IOC-本质"><a href="#IOC-本质" class="headerlink" title="IOC 本质"></a>IOC 本质</h3><p><strong>IOC 控制反转是一种设计思想，DI(依赖注入) 是实现 IOC 的一种方法。</strong>没有 IOC 的程序中，我们使用面向对象编程，对象的创建与对象间的依赖关系完全硬编码在程序中，对象的创建由程序自己控制。控制反转之后将对象的创建转移给第三方，个人理解控制反转就是：<strong>获得依赖对象的方式发生转变了</strong>。</p>
<p><strong>IOC 是 Spring 框架的核心内容</strong>，使用多种方式完美的实现的 Ioc，可以使用 xml 配置，也可以使用注解，新版本的 Spring 也可以零配置实现 IOC（自动装配）。</p>
<p>采用 xml 方式配置 Bean 的时候，Bean 的定义信息和实现是分离的，采用注解的方式可以把两者合为一体。Bean 的定义信息直接以注解的形式在定义在实现类中，从而达到零配置的目的。</p>
<p><strong>控制反转是一种通过描述 xml 或者注解，并通过第三方去生产或获取特定对象的方式。在 Spring 中实现控制反转的是 IOC 容器，其实现方式是依赖注入</strong>。</p>
<h2 id="3、HelloSpring"><a href="#3、HelloSpring" class="headerlink" title="3、HelloSpring"></a>3、HelloSpring</h2><pre><code class="java">public class Hello &#123;
    private String str;

    @Override
    public String toString() &#123;
        return &quot;Hello&#123;&quot; +
                &quot;str=&#39;&quot; + str + &#39;\&#39;&#39; +
                &#39;&#125;&#39;;
    &#125;

    public String getStr() &#123;
        return str;
    &#125;

    public void setStr(String str) &#123;
        this.str = str;
    &#125;
&#125;
</code></pre>
<p><a target="_blank" rel="noopener" href="https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core">https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core</a></p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;hello&quot; class=&quot;com.kuang.pojo.Hello&quot;&gt;
        &lt;property name=&quot;str&quot; value=&quot;Hello Spring&quot;/&gt;
        &lt;!--
            ref：引用Spring容器中创建好的对象
            value：引用具体的值，基本数据类型
        --&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</code></pre>
<pre><code class="java">public class MyTest &#123;
    public static void main(String[] args) &#123;
        //获取ApplicationContext：拿取Spring的容器
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);

        //需要什么，就get什么
        Hello hello = (Hello) context.getBean(&quot;hello&quot;);

        System.out.println(hello.toString());
    &#125;
&#125;
</code></pre>
<ul>
<li>Hello 对象是谁创建的？<ul>
<li>hello 对象是由 Spring 创建的</li>
</ul>
</li>
<li>Hello 对象的属性是怎么设置的<ul>
<li>hello 对象的属性是由 Spring 容器设置的</li>
</ul>
</li>
</ul>
<p>上面就用配置文件的形式，实现了控制反转</p>
<p>控制：谁来控制对象的创建，传统应用程序的对象是有程序本身来控制创建的，使用 Spring 后，对象是由 Spring 来创建</p>
<p>反转：程序本身不创建对象，而变成被动的接收对象</p>
<p>依赖注入：利用 set 的方法来进行注入</p>
<p>IOC 是一种变成思想，由主动的编程变成被动的编程</p>
<p>所谓 IOC 就是：对象由 Spring 来创建，管理，装配！</p>
<h2 id="4、IOC-创建对象的方式"><a href="#4、IOC-创建对象的方式" class="headerlink" title="4、IOC 创建对象的方式"></a>4、IOC 创建对象的方式</h2><pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;!--默认无参构造，有参会报错--&gt;
    &lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot;&gt;
        &lt;property name=&quot;name&quot; value=&quot;saber01&quot;/&gt;
    &lt;/bean&gt;

    &lt;!--第一种：构造函数参数名赋值--&gt;
    &lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot;&gt;
        &lt;constructor-arg name=&quot;name&quot; value=&quot;saber02&quot;/&gt;
    &lt;/bean&gt;

    &lt;!--第二种：构造函数参数索引赋值--&gt;
    &lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot;&gt;
        &lt;constructor-arg index=&quot;0&quot; value=&quot;saber02&quot;/&gt;
    &lt;/bean&gt;

    &lt;!--第三种：构造函数参数类型匹配赋值--&gt;
    &lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot;&gt;
        &lt;constructor-arg type=&quot;java.lang.String&quot; value=&quot;saber02&quot;/&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</code></pre>
<p>总结：在配置文件加载时，容器中管理的对象就已经被初始化了，且是单例的</p>
<h2 id="5、Spring-配置"><a href="#5、Spring-配置" class="headerlink" title="5、Spring 配置"></a>5、Spring 配置</h2><h3 id="5-1、别名"><a href="#5-1、别名" class="headerlink" title="5.1、别名"></a>5.1、别名</h3><pre><code class="xml">&lt;alias name=&quot;user&quot; alias=&quot;userNew&quot;/&gt;
</code></pre>
<pre><code class="java">User user = (User) context.getBean(&quot;userNew&quot;);
</code></pre>
<p>添加了别名(alias)，可以用别名获取对象</p>
<h3 id="5-2、Bean-的配置"><a href="#5-2、Bean-的配置" class="headerlink" title="5.2、Bean 的配置"></a>5.2、Bean 的配置</h3><pre><code class="xml">&lt;!--
    id：bean的唯一标识，相当于对象名
    class：bean对象所对应的全限定名：包名+类型
    name：也是别名，而且name可以同时取多个，可以用各种符号分开
--&gt;
&lt;bean id=&quot;hello&quot; class=&quot;com.kuang.pojo.Hello&quot; name=&quot;user2 u2;u3,u4&quot;&gt;
    &lt;property name=&quot;str&quot; value=&quot;Hello Spring&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<h3 id="5-3、import"><a href="#5-3、import" class="headerlink" title="5.3、import"></a>5.3、import</h3><p>一般用于团队开发，可以将多个配置文件合并成一个:applicationContext.xml</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;import resource=&quot;beans.xml&quot;/&gt;
    &lt;import resource=&quot;beans02.xml&quot;/&gt;

&lt;/beans&gt;
</code></pre>
<p>更多的信息可以前往</p>
<p>进行查看</p>
<h2 id="6、依赖注入"><a href="#6、依赖注入" class="headerlink" title="6、依赖注入"></a>6、依赖注入</h2><h3 id="6-1、构造器方式注入"><a href="#6-1、构造器方式注入" class="headerlink" title="6.1、构造器方式注入"></a>6.1、构造器方式注入</h3><p>上面的就是</p>
<h3 id="6-2、Set-方式注入【重点】"><a href="#6-2、Set-方式注入【重点】" class="headerlink" title="6.2、Set 方式注入【重点】"></a>6.2、Set 方式注入【重点】</h3><ul>
<li>依赖注入：Set 注入<ul>
<li>依赖：bean 对象的创建依赖于容器</li>
<li>注入：bean 对象中的所有属性，由容器来注入</li>
</ul>
</li>
</ul>
<p>【环境搭建】</p>
<ol>
<li><p>复杂类型</p>
<pre><code class="java">public class Address &#123;
    private String address;

    public String getAddress() &#123;
        return address;
    &#125;

    public void setAddress(String address) &#123;
        this.address = address;
    &#125;
&#125;
</code></pre>
</li>
<li><p>真实测试对象</p>
<pre><code class="java">//get set略
public class Student &#123;
    private String name;
    private Address address;
    private String[] books;
    private List&lt;String&gt; hobbys;
    private Map&lt;String,String&gt; card;
    private Set&lt;String&gt; games;
    private String wife;
    private Properties info;
&#125;
</code></pre>
</li>
<li><p>beans.xml</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;student&quot; class=&quot;com.kuang.pojo.Student&quot;&gt;
        &lt;property name=&quot;name&quot; value=&quot;saber&quot;/&gt;
    &lt;/bean&gt;

&lt;/beans&gt;
</code></pre>
</li>
<li><p>测试类</p>
<pre><code class="java">public class MyTest &#123;
    public static void main(String[] args) &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;beans.xml&quot;);

        Student student = (Student) context.getBean(&quot;student&quot;);

        System.out.println(student.toString());
    &#125;
&#125;
</code></pre>
</li>
</ol>
<p>完善注入信息</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;bean id=&quot;address&quot; class=&quot;com.kuang.pojo.Address&quot;&gt;
        &lt;property name=&quot;address&quot; value=&quot;000000000000000&quot;/&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;student&quot; class=&quot;com.kuang.pojo.Student&quot;&gt;

        &lt;property name=&quot;name&quot; value=&quot;saber&quot;/&gt;
        &lt;property name=&quot;address&quot; ref=&quot;address&quot;/&gt;

        &lt;!--数组--&gt;
        &lt;property name=&quot;books&quot;&gt;
            &lt;array&gt;
                &lt;value&gt;a1&lt;/value&gt;
                &lt;value&gt;a2&lt;/value&gt;
                &lt;value&gt;a3&lt;/value&gt;
                &lt;value&gt;a4&lt;/value&gt;
            &lt;/array&gt;
        &lt;/property&gt;

        &lt;!--list--&gt;
        &lt;property name=&quot;hobbys&quot;&gt;
            &lt;list&gt;
                &lt;value&gt;l1&lt;/value&gt;
                &lt;value&gt;l2&lt;/value&gt;
                &lt;value&gt;l3&lt;/value&gt;
                &lt;value&gt;l4&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;

        &lt;!--Map--&gt;
        &lt;property name=&quot;card&quot;&gt;
            &lt;map&gt;
                &lt;entry key=&quot;a&quot; value=&quot;a1&quot;/&gt;
                &lt;entry key=&quot;b&quot; value=&quot;b2&quot;/&gt;
                &lt;entry key=&quot;c&quot; value=&quot;c3&quot;/&gt;
            &lt;/map&gt;
        &lt;/property&gt;

        &lt;!--Set--&gt;
        &lt;property name=&quot;games&quot;&gt;
            &lt;set&gt;
                &lt;value&gt;s1&lt;/value&gt;
                &lt;value&gt;s2&lt;/value&gt;
                &lt;value&gt;s3&lt;/value&gt;
            &lt;/set&gt;
        &lt;/property&gt;

        &lt;!--null--&gt;
        &lt;property name=&quot;wife&quot;&gt;
            &lt;null&gt;&lt;/null&gt;
        &lt;/property&gt;

        &lt;!--Properties--&gt;
        &lt;property name=&quot;info&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;Email_1&quot;&gt;1347216032@qq.com&lt;/prop&gt;
                &lt;prop key=&quot;Email_2&quot;&gt;3081453914@qq.com&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</code></pre>
<h3 id="6-3、拓展方式注入"><a href="#6-3、拓展方式注入" class="headerlink" title="6.3、拓展方式注入"></a>6.3、拓展方式注入</h3><h3 id="C-与-P-命名空间"><a href="#C-与-P-命名空间" class="headerlink" title="C 与 P 命名空间"></a>C 与 P 命名空间</h3><pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
       xmlns:c=&quot;http://www.springframework.org/schema/c&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd&quot;&gt;

    &lt;!--p命名空间注入，可以直接注入属性的值：property--&gt;
    &lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot; p:name=&quot;saber-u&quot; p:age=&quot;18&quot;&gt;&lt;/bean&gt;

    &lt;!--c命名空间注入，通过构造器注入属性的值：construct-args--&gt;
    &lt;bean id=&quot;user2&quot; class=&quot;com.kuang.pojo.User&quot; c:name=&quot;saber-u-2&quot; c:age=&quot;20&quot;/&gt;

&lt;/beans&gt;
</code></pre>
<p>测试</p>
<pre><code class="java">@Test
public void test2()&#123;
    ApplicationContext context = new ClassPathXmlApplicationContext(&quot;userbeans.xml&quot;);
    User user = context.getBean(&quot;user2&quot;, User.class);

    System.out.println(user.toString());
&#125;
</code></pre>
<p>注意：p/c 命名空间不能直接使用，要引入 xml 约束</p>
<pre><code class="xml">xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
xmlns:c=&quot;http://www.springframew
</code></pre>
<h3 id="6-4、bean-的作用域"><a href="#6-4、bean-的作用域" class="headerlink" title="6.4、bean 的作用域"></a>6.4、bean 的作用域</h3><p><img src="/2021/03/28/Spring/image-20210324163350637.png" alt="image-20210324163350637" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210324163350637.png" class="lozad post-image"></p>
<ol>
<li><p>单例模式（spring 的默认模式）</p>
<pre><code class="xml">&lt;!-- the following is equivalent, though redundant (singleton scope is the default) --&gt;
&lt;bean id=&quot;accountService&quot; class=&quot;com.something.DefaultAccountService&quot; scope=&quot;singleton&quot;/&gt;
</code></pre>
<p><img src="/2021/03/28/Spring/image-20210324163751380.png" alt="image-20210324163751380" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210324163751380.png" class="lozad post-image"></p>
</li>
<li><p>原型模式：每次从容器 get 的时候，都会产生一个新的对象</p>
<pre><code class="xml">&lt;bean id=&quot;accountService&quot; class=&quot;com.something.DefaultAccountService&quot; scope=&quot;prototype&quot;/&gt;
</code></pre>
<p><img src="/2021/03/28/Spring/image-20210324163817956.png" alt="image-20210324163817956" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210324163817956.png" class="lozad post-image"></p>
</li>
<li><p>其余的<code>request</code>，<code>session</code>，<code>applicatoin</code>这些只能在 web 开发中使用！</p>
</li>
</ol>
<h2 id="7、Bean-的自动装配"><a href="#7、Bean-的自动装配" class="headerlink" title="7、Bean 的自动装配"></a>7、Bean 的自动装配</h2><ul>
<li>自动装配是 Spring 满足 bean 依赖的一种方式</li>
<li>Spring 会在上下文中自动寻找，并自动给 bean 装配属性</li>
</ul>
<p>在 Spring 中有三种装配方式</p>
<ol>
<li>在 xml 中显示的配置</li>
<li>在 java 中显示配置</li>
<li><strong>隐式的自动装配 bean</strong></li>
</ol>
<h3 id="7-1、ByName-自动装配"><a href="#7-1、ByName-自动装配" class="headerlink" title="7.1、ByName 自动装配"></a>7.1、ByName 自动装配</h3><pre><code class="xml">&lt;bean id=&quot;cat&quot; class=&quot;com.kuang.pojo.Cat&quot;&gt;&lt;/bean&gt;
&lt;bean id=&quot;dog&quot; class=&quot;com.kuang.pojo.Dog&quot;&gt;&lt;/bean&gt;

&lt;!--
    byName:会自动在容器中上下文查找，和自己对象set方法后面的值对应的beanid
--&gt;
&lt;bean id=&quot;perple&quot; class=&quot;com.kuang.pojo.People&quot; autowire=&quot;byName&quot;&gt;
    &lt;property name=&quot;name&quot; value=&quot;saber&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<h3 id="7-2、ByType-自动装配"><a href="#7-2、ByType-自动装配" class="headerlink" title="7.2、ByType 自动装配"></a>7.2、ByType 自动装配</h3><pre><code class="xml">&lt;bean id=&quot;cat&quot; class=&quot;com.kuang.pojo.Cat&quot;&gt;&lt;/bean&gt;
&lt;bean id=&quot;dog&quot; class=&quot;com.kuang.pojo.Dog&quot;&gt;&lt;/bean&gt;

&lt;!--
    byType:会自动在容器中上下文查找，和自己对象属性类型相同的bean，
--&gt;
&lt;bean id=&quot;perple&quot; class=&quot;com.kuang.pojo.People&quot; autowire=&quot;byType&quot;&gt;
    &lt;property name=&quot;name&quot; value=&quot;saber&quot;/&gt;
&lt;/bean&gt;
</code></pre>
<p>小结：</p>
<ul>
<li>byname 的时候，需要保证所有 bean 的 id 唯一，并且这个 bean 需要和自动注入的属性的 set 方法的值一致</li>
<li>bytype 的时候，需要保证所有 bean 的 class 唯一，并且这个 bean 需要和自动注入的属的类型一致</li>
</ul>
<h3 id="7-3、使用注解实现自动装配"><a href="#7-3、使用注解实现自动装配" class="headerlink" title="7.3、使用注解实现自动装配"></a>7.3、使用注解实现自动装配</h3><p>jdk1.5 支持的注解，Spring2.5 就支持注解了</p>
<p>The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.</p>
<p>使用注解须知：</p>
<ol>
<li><p>导入约束</p>
</li>
<li><p><strong>配置注解的支持</strong></p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
    xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;
    &lt;context:annotation-config/&gt;
&lt;/beans&gt;
</code></pre>
</li>
</ol>
<p><strong>@Autowired</strong></p>
<p>直接在属性上使用即可，也可以在 set 方法使用</p>
<p>使用 Autowired 我们可以不用编写 Set 方法，前提是你这个自动装配的属性在 IOC（Spring）容器中存在，且符合名字 byname</p>
<p>@Autowired 默认根据类型进行匹配，若 xml 中同时存在多个相同类型时，则按名称进行匹配，若没用相同名称的配置时，<strong>则需要使用@Qualifier(value = “name”)注解进行指定</strong>，同时@Autowired 中还存在 required 属性，默认为 true，若为 false 时，说明对象可以为 null，否则不允许为空</p>
<pre><code class="xml">    &lt;bean id=&quot;cat&quot; class=&quot;com.kuang.pojo.Cat&quot;&gt;&lt;/bean&gt;
&lt;!--    &lt;bean id=&quot;dog&quot; class=&quot;com.kuang.pojo.Dog&quot;&gt;&lt;/bean&gt;--&gt;
    &lt;bean id=&quot;dog2&quot; class=&quot;com.kuang.pojo.Dog&quot;&gt;&lt;/bean&gt;
    &lt;bean id=&quot;dog22&quot; class=&quot;com.kuang.pojo.Dog&quot;&gt;&lt;/bean&gt;

    &lt;bean id=&quot;perple&quot; class=&quot;com.kuang.pojo.People&quot;&gt;
        &lt;property name=&quot;name&quot; value=&quot;saber&quot;/&gt;
    &lt;/bean&gt;
</code></pre>
<pre><code class="java">    @Autowired
    private Cat cat;

    @Autowired
    @Qualifier(value = &quot;dog22&quot;)
    private Dog dog;

    private String name;
</code></pre>
<p><strong>@Resource</strong></p>
<pre><code class="java">    @Resource(name = &quot;cat22&quot;)
    private Cat cat;

    @Resource
    private Dog dog;
</code></pre>
<p>小结：</p>
<p>@Resource 和@Autowired 的区别：</p>
<ul>
<li>都是用于自动装配，都可以放在字段上</li>
<li>@Autowired 通过 bytype 的方式实现，而且对象必须存在</li>
<li>@Resource 默认通过 byname 实现，如果找不到名字，则通过 bytyoe 实现，如果两个都找不到，则报错</li>
</ul>
<h2 id="8、使用注解开发"><a href="#8、使用注解开发" class="headerlink" title="8、使用注解开发"></a>8、使用注解开发</h2><pre><code class="xml">&lt;!--注意：需要引入AOP包--&gt;
&lt;!--需要扫描的包--&gt;
&lt;context:component-scan base-package=&quot;com.kuang.pojo&quot;/&gt;
&lt;context:annotation-config/&gt;
</code></pre>
<p><img src="/2021/03/28/Spring/image-20210324191701964.png" alt="image-20210324191701964" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210324191701964.png" class="lozad post-image"></p>
<p><strong>@Component</strong> 组件</p>
<pre><code class="java">//等价于&lt;bean id=&quot;user&quot; class=&quot;com.kuang.pojo.User&quot;/&gt; 无须在xml中写
@Component
public class User &#123;
    public String name=&quot;saber&quot;;
&#125;
</code></pre>
<p>@Value</p>
<pre><code class="java">@Component
public class User &#123;
    //等价于 &lt;property name=&quot;name&quot; value=&quot;saber&quot;/&gt;
    @Value(&quot;SABER&quot;)
    public String name;
&#125;
</code></pre>
<p>@Component 衍生注解，根据不同的层使用不同的注解</p>
<ol>
<li>dao 层【@Repository】</li>
<li>service 层【@Service】</li>
<li>controller 层【@Controller】</li>
</ol>
<p>这四个注解功能都是一样的，都代表将某个类注册到 Spring 中，装配 Bean</p>
<p>作用域也可以直接通过<code>@Scope(&quot;&quot;)</code>实现</p>
<p>小结：</p>
<p>xml 与注解：</p>
<ul>
<li>xml 更加万能，适用于各种场合，维护简单</li>
<li>注解不是自己类使用不了，维护相对复杂</li>
</ul>
<p>xml 与注解的最佳实践：</p>
<ul>
<li><p>xml 来管理 bean</p>
</li>
<li><p>注解只负责完成属性的注入</p>
</li>
<li><p>我们使用中，只需要注意一个问题：必须让注解生效，就需要开启注解的支持</p>
<pre><code class="xml">&lt;!--需要扫描的包--&gt;
&lt;context:component-scan base-package=&quot;com.kuang&quot;/&gt;
&lt;context:annotation-config/&gt;
</code></pre>
</li>
</ul>
<h2 id="9、使用-Java-的方式配置-Spring"><a href="#9、使用-Java-的方式配置-Spring" class="headerlink" title="9、使用 Java 的方式配置 Spring"></a>9、使用 Java 的方式配置 Spring</h2><p>JavaConfig 是 Spring 的一个子项目</p>
<p>实体类：</p>
<pre><code class="java">package com.kuang.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

//@Component
public class User &#123;
    @Value(&quot;saber&quot;)
    private String name;

    public String getName() &#123;
        return name;
    &#125;

    public void setName(String name) &#123;
        this.name = name;
    &#125;

    @Override
    public String toString() &#123;
        return &quot;User&#123;&quot; +
                &quot;name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &#39;&#125;&#39;;
    &#125;
&#125;
</code></pre>
<p>配置文件类：</p>
<pre><code class="java">package com.kuang.config;

import com.kuang.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

//这个也会被Spring容器托管，注册到容器中，因为它本身就是一个@Component
//@Configuration表示这是一个配置类，就是之前的beans.xml
@Configuration
//@ComponentScan(&quot;com.kuang.pojo&quot;) //扫描指定包
@Import(SaberConfig2.class) //相当于Import标签
public class SaberConfig &#123;

    //注册一个bean 相当于之前的&lt;bean&gt;标签
    //方法名相当于bean标签的id
    //返回值相当于bean标签的class属性
    @Bean
    public User getUser()&#123;
        return new User();//我们要注入到bean的对象
    &#125;
&#125;
//如果你没用扫描指定包@ComponentScan(&quot;com.kuang.pojo&quot;) 则必须使用@Bean主动进行配置，
//如果使用@ComponentScan(&quot;com.kuang.pojo&quot;)扫描，则扫描对象必须包含@Component
</code></pre>
<p>测试方法:</p>
<pre><code class="java">    public static void main(String[] args) &#123;
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SaberConfig.class);
        User user = ctx.getBean(User.class);//也可以用方法名getUser,也可以用@Bean指定的名称
        System.out.println(user.getName());
    &#125;
</code></pre>
<h2 id="10、代理模式"><a href="#10、代理模式" class="headerlink" title="10、代理模式"></a>10、代理模式</h2><p>代理模式的分类：</p>
<ul>
<li>静态代理</li>
<li>动态代理</li>
</ul>
<p><img src="/2021/03/28/Spring/image-20210325152819245.png" alt="image-20210325152819245" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210325152819245.png" class="lozad post-image"></p>
<h3 id="10-1、静态代理"><a href="#10-1、静态代理" class="headerlink" title="10.1、静态代理"></a>10.1、静态代理</h3><p>角色分析：</p>
<ul>
<li>抽象角色：一般会使用接口或抽象类来解决</li>
<li>真实角色：被代理的角色</li>
<li>代理角色：代理真实角色，代理真实角色后，我们一般会做一些附属操作</li>
<li>客户：访问代理对象</li>
</ul>
<p>代码步骤：</p>
<ol>
<li><p>接口</p>
<pre><code class="java">//租房
public interface Rent &#123;
    public void rent();
&#125;
</code></pre>
</li>
<li><p>真实角色</p>
<pre><code class="java">public class Host implements Rent&#123;
    @Override
    public void rent() &#123;
        System.out.println(&quot;房东要租房子&quot;);
    &#125;
&#125;
</code></pre>
</li>
<li><p>代理角色</p>
<pre><code class="java">public class Proxy implements Rent&#123;

    private Host host;

    public Proxy() &#123;
    &#125;

    public Proxy(Host host) &#123;
        this.host = host;
    &#125;

    @Override
    public void rent() &#123;
        seeHouse();
        host.rent();
        hetong();
        fare();
    &#125;

    public void seeHouse()&#123;
        System.out.println(&quot;kan fang&quot;);
    &#125;

    public void hetong()&#123;
        System.out.println(&quot;qian he tong&quot;);
    &#125;

    public void fare()&#123;
        System.out.println(&quot;shou zhong jie fei&quot;);
    &#125;
&#125;
</code></pre>
</li>
<li><p>客户端访问代理角色</p>
<pre><code class="java">    public static void main(String[] args) &#123;
        Host host = new Host();
//        host.rent();

        Proxy proxy = new Proxy(host);
        proxy.rent();
    &#125;
</code></pre>
</li>
</ol>
<p>代理模式的好处：</p>
<ul>
<li>可以使真实角色的操作更加纯粹，不用去关注一些公共服务</li>
<li>公共服务交给代理角色，实现业务划分</li>
<li>公共业务发生扩展时，方便集中管理</li>
</ul>
<p>缺点：</p>
<ul>
<li>一个真实角色就会产生一个代理角色，代码量翻倍，开发效率变低</li>
</ul>
<h3 id="10-2、动态代理"><a href="#10-2、动态代理" class="headerlink" title="10.2、动态代理"></a>10.2、动态代理</h3><ul>
<li>动态代理和静态代理角色一样</li>
<li>动态代理的代理类是动态生成的，不是写好的</li>
<li>动态代理分为两大类：基于接口的动态代理，基于类的动态代理<ul>
<li>基于接口：JDK 实现动态代理</li>
<li>基于类：cglib</li>
<li>java 字节码实现：javasist</li>
</ul>
</li>
</ul>
<p>需要了解两个类：Proxy：代理， InvocationHandler：调用处理程序</p>
<p>动态代理的好处：</p>
<ul>
<li>可以使真实角色的操作更加纯粹，不用去关注一些公共服务</li>
<li>公共服务交给代理角色，实现业务划分</li>
<li>公共业务发生扩展时，方便集中管理</li>
<li>一个动态代理类代理的是一个接口，一般是对应的一类业务</li>
<li>一个动态代理类可以代理多个类，只要实现了同一个接口即可</li>
</ul>
<p>动态代理的代码实现：</p>
<pre><code class="java">import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class StarProxy implements InvocationHandler
&#123;
    // 目标类，也就是被代理对象
    private Object target;

    public void setTarget(Object target)
    &#123;
        this.target = target;
    &#125;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    &#123;
        // 这里可以做增强
        System.out.println(&quot;收钱&quot;);

        Object result = method.invoke(target, args);

        return result;
    &#125;

    // 生成代理类
    public Object CreatProxyedObj()
    &#123;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    &#125;

&#125;
</code></pre>
<h2 id="11、AOP"><a href="#11、AOP" class="headerlink" title="11、AOP"></a>11、AOP</h2><h3 id="11-1、什么是-AOP"><a href="#11-1、什么是-AOP" class="headerlink" title="11.1、什么是 AOP"></a>11.1、什么是 AOP</h3><p>AOP（Aspect Oriented Programming）称为面向切面编程，在程序开发中主要用来解决一些系统层面上的问题，比如日志，事务，权限等待，AOP 是 OOP 的延续，是软件开发中的热点，是函数是编程的一种衍生范型，利用 AOP 可以对业务逻辑的各部分进行隔离，从而使业务逻辑各部分之间的耦合降低，提高可重用性。</p>
<h3 id="11-2、AOP-在-Spring-的作用"><a href="#11-2、AOP-在-Spring-的作用" class="headerlink" title="11.2、AOP 在 Spring 的作用"></a>11.2、AOP 在 Spring 的作用</h3><p><strong>提供声明性事务，允许用户自定义切面</strong></p>
<ul>
<li>横切关注点：跨越应用程序多个模块的方法或功能，即是，与我们业务逻辑无关，但是我们需要关注的部分，就是横切关注点，如日志，安全，缓存，事务等等….</li>
<li>切面（ASPECT）：横切关注点 被模块化 的特殊对象。即，它是一个类。</li>
<li>通知（Advice）：切面必须要完成的工作。即，它是类中的一个方法。</li>
<li>目标（Target）：被通知的对象。</li>
<li>代理（Proxy）：向目标对象应用通知之后创建的对象</li>
<li>切入点（PointCut）：切面通知 执行的“地点”的定义</li>
<li>连接点（JointPoint）：与切入点匹配的执行点</li>
</ul>
<p><img src="/2021/03/28/Spring/image-20210326092139762.png" alt="image-20210326092139762" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210326092139762.png" class="lozad post-image"></p>
<p>SpringAOP 中，通过 Advice 定义横切逻辑，Spring 中支持 5 种类型的 Advice：</p>
<p><img src="/2021/03/28/Spring/image-20210326092851839.png" alt="image-20210326092851839" srcset="data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20300%20300'%3E%3C/svg%3E" data-src="/2021/03/28/Spring/image-20210326092851839.png" class="lozad post-image"></p>
<p>即 AOP 在不改变原有代码的情况下，去增加新的功能</p>
<h3 id="11-3、使用-Spring-实现-AOP"><a href="#11-3、使用-Spring-实现-AOP" class="headerlink" title="11.3、使用 Spring 实现 AOP"></a>11.3、使用 Spring 实现 AOP</h3><p><strong>使用 AOP 织入，需要导入一个依赖包</strong></p>
<pre><code class="xml">&lt;dependency&gt;
    &lt;groupId&gt;org.aspectj&lt;/groupId&gt;
    &lt;artifactId&gt;aspectjweaver&lt;/artifactId&gt;
    &lt;version&gt;1.9.4&lt;/version&gt;
&lt;/dependency&gt;
</code></pre>
<h4 id="方法一：使用-Spring-接口"><a href="#方法一：使用-Spring-接口" class="headerlink" title="方法一：使用 Spring 接口"></a>方法一：使用 Spring 接口</h4><pre><code class="java">@Component
public class Log implements MethodBeforeAdvice &#123;
    //method：要执行的目标对象的方法
    //objects：参数
    //o：目标对象
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable &#123;
        System.out.println(o.getClass().getName() +&quot;的&quot;+method.getName()+&quot;方法被执行&quot;);
    &#125;
&#125;
</code></pre>
<pre><code class="java">@Component
public class AfterLog implements AfterReturningAdvice &#123;
    //returnValue：返回值
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable &#123;
        System.out.println(&quot;执行了&quot;+method.getName() +&quot;方法,返回结果:&quot;+returnValue);
    &#125;
&#125;
</code></pre>
<p>上面实现两个测试用的切面方法</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd&quot;&gt;

    &lt;context:component-scan base-package=&quot;com.kuang&quot;/&gt;
    &lt;context:annotation-config/&gt;

    &lt;!--方法一：使用原生SpringAPI接口--&gt;
    &lt;!--配置aop：需要导入aop约束--&gt;
    &lt;aop:config&gt;
        &lt;!--DOTO:切入点：expression：表达式，execution(要执行的位置！)--&gt;
        &lt;aop:pointcut id=&quot;pointuct&quot; expression=&quot;execution(* com.kuang.service.UserServiceImpl.*(..))&quot;/&gt;

        &lt;!--要执行的环绕增加--&gt;
        &lt;aop:advisor advice-ref=&quot;afterLog&quot; pointcut-ref=&quot;pointuct&quot;/&gt;
        &lt;aop:advisor advice-ref=&quot;log&quot; pointcut-ref=&quot;pointuct&quot;/&gt;
    &lt;/aop:config&gt;

&lt;/beans&gt;
</code></pre>
<pre><code class="java">public class MyTest &#123;
    public static void main(String[] args) &#123;
        ApplicationContext context = new ClassPathXmlApplicationContext(&quot;applicationContext.xml&quot;);
        UserService userService = context.getBean(&quot;userServiceImpl&quot;,UserService.class);

        userService.add();
    &#125;
&#125;
</code></pre>
<h4 id="方法二：自定义类实现-AOP"><a href="#方法二：自定义类实现-AOP" class="headerlink" title="方法二：自定义类实现 AOP"></a>方法二：自定义类实现 AOP</h4><p>将配置文件修改为：</p>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd&quot;&gt;

    &lt;context:component-scan base-package=&quot;com.kuang&quot;/&gt;
    &lt;context:annotation-config/&gt;

    &lt;!--方法二：自定义类--&gt;
    &lt;aop:config&gt;
        &lt;!--自定义切面，ref要引用的类--&gt;
        &lt;aop:aspect ref=&quot;diyPintCut&quot;&gt;
            &lt;!--切入点--&gt;
            &lt;aop:pointcut id=&quot;point&quot; expression=&quot;execution(* com.kuang.service.UserServiceImpl.*(..))&quot;/&gt;

            &lt;!--通知--&gt;
            &lt;aop:after method=&quot;after&quot; pointcut-ref=&quot;point&quot;/&gt;
            &lt;aop:before method=&quot;before&quot; pointcut-ref=&quot;point&quot;/&gt;
        &lt;/aop:aspect&gt;
    &lt;/aop:config&gt;

&lt;/beans&gt;
</code></pre>
<p>实现的自定义类：</p>
<pre><code class="java">import org.springframework.stereotype.Component;
@Component
public class DiyPintCut &#123;
    public void before()&#123;
        System.out.println(&quot;=======berfre========&quot;);
    &#125;
    public void after()&#123;
        System.out.println(&quot;=======after========&quot;);
    &#125;
&#125;
</code></pre>
<h4 id="方式三：使用注解实现"><a href="#方式三：使用注解实现" class="headerlink" title="方式三：使用注解实现"></a>方式三：使用注解实现</h4><pre><code class="java">import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect //标注这是一个切面
@Component
public class AnnotationPointCut &#123;
    @Before(&quot;execution(* com.kuang.service.UserServiceImpl.*(..))&quot;)//注意 这是annotation包下的注解
    public void before() &#123;
        System.out.println(&quot;=======berfre========&quot;);
    &#125;

    @After(&quot;execution(* com.kuang.service.UserServiceImpl.*(..))&quot;)
    public void after() &#123;
        System.out.println(&quot;=======after========&quot;);
    &#125;

    //在环绕增强中，我们可以定一个参数，代表我们要获取处理的切入点
    @Around(&quot;execution(* com.kuang.service.UserServiceImpl.*(..))&quot;)
    public void around(ProceedingJoinPoint jp) throws Throwable &#123;
        System.out.println(&quot;before-around&quot;);
        System.out.println(jp.getSignature());//获取签名

        Object proceed = jp.proceed();//执行方法 proceed：返回值

        System.out.println(&quot;after-around&quot;);
        System.out.println(proceed);
    &#125;
&#125;
</code></pre>
<pre><code class="xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
       xmlns:aop=&quot;http://www.springframework.org/schema/aop&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd&quot;&gt;

    &lt;context:component-scan base-package=&quot;com.kuang&quot;/&gt;
    &lt;context:annotation-config/&gt;
    &lt;!--开启注解支持 需要添加这个才能使用注解AOP--&gt;
    &lt;!--有一个参数 默认为false 则为使用JDK实现动态代理 true则使用cglib   proxy-target-class=&quot;true&quot;--&gt;
    &lt;aop:aspectj-autoproxy/&gt;

&lt;/beans&gt;
</code></pre>
<p>参考：</p>
<p>文章：<a target="_blank" rel="noopener" href="https://www.jianshu.com/p/34efe69582c8">https://www.jianshu.com/p/34efe69582c8</a></p>

  </div>
  <div>
    
      <div 
        class="post-note note-warning copyright" 
        style="margin-top: 42px">
        <p>
          <span style="font-weight: bold;">作者：</span><a 
            target="_blank" 
            rel="nofollow noopener noreferrer" 
            href="/about">
            Gas
          </a>
        </p>
        <p>
          <span style="font-weight: bold;">文章链接：</span><a 
            target="_blank" 
            rel="nofollow noopener noreferrer" 
            href="http://example.com/2021/03/28/Spring/">
            http://example.com/2021/03/28/Spring/
          </a>
        </p>
        <p><span style="font-weight: bold;">版权声明：</span>本博客所有文章除特别声明外，均采用<a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">CC BY-NC-SA 4.0 协议</a>。转载请注明出处！</p>
      </div>
    
  </div>
</article>
<div class="nav">
  
    <div class="nav-item-prev">
      <a 
        href="/2021/04/01/IDEA%E7%94%A8Maven%E5%88%9B%E5%BB%BASpringMVC%E9%A1%B9%E7%9B%AE/" 
        class="nav-link">
        <i class="iconfont icon-left nav-prev-icon"></i>
        <div>
          <div class="nav-label">上一篇</div>
          
            <div class="nav-title">IDEA用Maven创建SpringMVC项目 </div>
          
        </div>
      </a>
    </div>
  
  
    <div class="nav-item-next">
      <a 
        href="/2021/03/19/SpringBoot%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A0%A1%E9%AA%8C%E6%B3%A8%E8%A7%A3/" 
        class="nav-link">
        <div>
          <div class="nav-label">下一篇</div>
          
            <div class="nav-title">SpringBoot自定义校验注解 </div>
          
        </div>
        <i class="iconfont icon-right nav-next-icon"></i>
      </a>
    </div>
  
</div>

<div 
  class="card card-content toc-card" 
  id="mobiletoc">
  <div class="toc-header">
  <i 
    class="iconfont icon-menu" 
    style="padding-right: 2px;">
  </i>目录
</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1%E3%80%81Spring"><span class="toc-number">1.</span> <span class="toc-text">1、Spring</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2%E3%80%81%E4%BC%98%E7%82%B9"><span class="toc-number">1.1.</span> <span class="toc-text">1.2、优点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-3%E3%80%81%E7%BB%84%E6%88%90"><span class="toc-number">1.2.</span> <span class="toc-text">1.3、组成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-4%E3%80%81%E6%8B%93%E5%B1%95"><span class="toc-number">1.3.</span> <span class="toc-text">1.4、拓展</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2%E3%80%81IOC-%E7%90%86%E8%AE%BA%E6%8E%A8%E5%AF%BC"><span class="toc-number">2.</span> <span class="toc-text">2、IOC 理论推导</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#IOC-%E6%9C%AC%E8%B4%A8"><span class="toc-number">2.1.</span> <span class="toc-text">IOC 本质</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3%E3%80%81HelloSpring"><span class="toc-number">3.</span> <span class="toc-text">3、HelloSpring</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4%E3%80%81IOC-%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E5%BC%8F"><span class="toc-number">4.</span> <span class="toc-text">4、IOC 创建对象的方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5%E3%80%81Spring-%E9%85%8D%E7%BD%AE"><span class="toc-number">5.</span> <span class="toc-text">5、Spring 配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1%E3%80%81%E5%88%AB%E5%90%8D"><span class="toc-number">5.1.</span> <span class="toc-text">5.1、别名</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2%E3%80%81Bean-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">5.2.</span> <span class="toc-text">5.2、Bean 的配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3%E3%80%81import"><span class="toc-number">5.3.</span> <span class="toc-text">5.3、import</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6%E3%80%81%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5"><span class="toc-number">6.</span> <span class="toc-text">6、依赖注入</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1%E3%80%81%E6%9E%84%E9%80%A0%E5%99%A8%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.1.</span> <span class="toc-text">6.1、构造器方式注入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-2%E3%80%81Set-%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5%E3%80%90%E9%87%8D%E7%82%B9%E3%80%91"><span class="toc-number">6.2.</span> <span class="toc-text">6.2、Set 方式注入【重点】</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-3%E3%80%81%E6%8B%93%E5%B1%95%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.3.</span> <span class="toc-text">6.3、拓展方式注入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#C-%E4%B8%8E-P-%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4"><span class="toc-number">6.4.</span> <span class="toc-text">C 与 P 命名空间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-4%E3%80%81bean-%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">6.5.</span> <span class="toc-text">6.4、bean 的作用域</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7%E3%80%81Bean-%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.</span> <span class="toc-text">7、Bean 的自动装配</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#7-1%E3%80%81ByName-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.1.</span> <span class="toc-text">7.1、ByName 自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-2%E3%80%81ByType-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.2.</span> <span class="toc-text">7.2、ByType 自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-3%E3%80%81%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.3.</span> <span class="toc-text">7.3、使用注解实现自动装配</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#8%E3%80%81%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91"><span class="toc-number">8.</span> <span class="toc-text">8、使用注解开发</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9%E3%80%81%E4%BD%BF%E7%94%A8-Java-%E7%9A%84%E6%96%B9%E5%BC%8F%E9%85%8D%E7%BD%AE-Spring"><span class="toc-number">9.</span> <span class="toc-text">9、使用 Java 的方式配置 Spring</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10%E3%80%81%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F"><span class="toc-number">10.</span> <span class="toc-text">10、代理模式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#10-1%E3%80%81%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86"><span class="toc-number">10.1.</span> <span class="toc-text">10.1、静态代理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#10-2%E3%80%81%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86"><span class="toc-number">10.2.</span> <span class="toc-text">10.2、动态代理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11%E3%80%81AOP"><span class="toc-number">11.</span> <span class="toc-text">11、AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#11-1%E3%80%81%E4%BB%80%E4%B9%88%E6%98%AF-AOP"><span class="toc-number">11.1.</span> <span class="toc-text">11.1、什么是 AOP</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-2%E3%80%81AOP-%E5%9C%A8-Spring-%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-number">11.2.</span> <span class="toc-text">11.2、AOP 在 Spring 的作用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-3%E3%80%81%E4%BD%BF%E7%94%A8-Spring-%E5%AE%9E%E7%8E%B0-AOP"><span class="toc-number">11.3.</span> <span class="toc-text">11.3、使用 Spring 实现 AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%9A%E4%BD%BF%E7%94%A8-Spring-%E6%8E%A5%E5%8F%A3"><span class="toc-number">11.3.1.</span> <span class="toc-text">方法一：使用 Spring 接口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%AE%9E%E7%8E%B0-AOP"><span class="toc-number">11.3.2.</span> <span class="toc-text">方法二：自定义类实现 AOP</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E5%BC%8F%E4%B8%89%EF%BC%9A%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0"><span class="toc-number">11.3.3.</span> <span class="toc-text">方式三：使用注解实现</span></a></li></ol></li></ol></li></ol>
</div></main>
            <aside class="left-column">
              
              <div class="card card-author">
                
  <img 
    src="/img/Kaze.png" 
    class="author-img" 
    alt="author avatar">

<p class="author-name">Gas</p>
<p class="author-description">想当画家的咸鱼罢了</p>
<div class="author-message">
  <a 
    class="author-posts-count" 
    href="/archives">
    <span>51</span>
    <span>文章</span>
  </a>
  <a 
    class="author-categories-count" 
    href="/categories">
    <span>16</span>
    <span>分类</span>
  </a>
  <a 
    class="author-tags-count" 
    href="/tags">
    <span>44</span>
    <span>标签</span>
  </a>
</div>

  <div class="author-card-society">
    
      <div class="author-card-society-icon">
        <a target="_blank" rel="noopener" href="https://github.com/Uranus-s">
          <i class="iconfont social_github icon-github society-icon"></i>
        </a>
      </div>
    
      <div class="author-card-society-icon">
        <a target="_blank" rel="noopener" href="https://gitee.com/L-sama">
          <i class="iconfont social_github icon-gitee2 society-icon"></i>
        </a>
      </div>
    
  </div>

              </div>
               <div class="sticky-tablet">
  
  
    <article class="display-when-two-columns spacer">
      <div class="card card-content toc-card">
        <div class="toc-header">
  <i 
    class="iconfont icon-menu" 
    style="padding-right: 2px;">
  </i>目录
</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1%E3%80%81Spring"><span class="toc-number">1.</span> <span class="toc-text">1、Spring</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2%E3%80%81%E4%BC%98%E7%82%B9"><span class="toc-number">1.1.</span> <span class="toc-text">1.2、优点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-3%E3%80%81%E7%BB%84%E6%88%90"><span class="toc-number">1.2.</span> <span class="toc-text">1.3、组成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-4%E3%80%81%E6%8B%93%E5%B1%95"><span class="toc-number">1.3.</span> <span class="toc-text">1.4、拓展</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2%E3%80%81IOC-%E7%90%86%E8%AE%BA%E6%8E%A8%E5%AF%BC"><span class="toc-number">2.</span> <span class="toc-text">2、IOC 理论推导</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#IOC-%E6%9C%AC%E8%B4%A8"><span class="toc-number">2.1.</span> <span class="toc-text">IOC 本质</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3%E3%80%81HelloSpring"><span class="toc-number">3.</span> <span class="toc-text">3、HelloSpring</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4%E3%80%81IOC-%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E5%BC%8F"><span class="toc-number">4.</span> <span class="toc-text">4、IOC 创建对象的方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5%E3%80%81Spring-%E9%85%8D%E7%BD%AE"><span class="toc-number">5.</span> <span class="toc-text">5、Spring 配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1%E3%80%81%E5%88%AB%E5%90%8D"><span class="toc-number">5.1.</span> <span class="toc-text">5.1、别名</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2%E3%80%81Bean-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">5.2.</span> <span class="toc-text">5.2、Bean 的配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3%E3%80%81import"><span class="toc-number">5.3.</span> <span class="toc-text">5.3、import</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6%E3%80%81%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5"><span class="toc-number">6.</span> <span class="toc-text">6、依赖注入</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1%E3%80%81%E6%9E%84%E9%80%A0%E5%99%A8%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.1.</span> <span class="toc-text">6.1、构造器方式注入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-2%E3%80%81Set-%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5%E3%80%90%E9%87%8D%E7%82%B9%E3%80%91"><span class="toc-number">6.2.</span> <span class="toc-text">6.2、Set 方式注入【重点】</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-3%E3%80%81%E6%8B%93%E5%B1%95%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.3.</span> <span class="toc-text">6.3、拓展方式注入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#C-%E4%B8%8E-P-%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4"><span class="toc-number">6.4.</span> <span class="toc-text">C 与 P 命名空间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-4%E3%80%81bean-%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">6.5.</span> <span class="toc-text">6.4、bean 的作用域</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7%E3%80%81Bean-%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.</span> <span class="toc-text">7、Bean 的自动装配</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#7-1%E3%80%81ByName-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.1.</span> <span class="toc-text">7.1、ByName 自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-2%E3%80%81ByType-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.2.</span> <span class="toc-text">7.2、ByType 自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-3%E3%80%81%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.3.</span> <span class="toc-text">7.3、使用注解实现自动装配</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#8%E3%80%81%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91"><span class="toc-number">8.</span> <span class="toc-text">8、使用注解开发</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9%E3%80%81%E4%BD%BF%E7%94%A8-Java-%E7%9A%84%E6%96%B9%E5%BC%8F%E9%85%8D%E7%BD%AE-Spring"><span class="toc-number">9.</span> <span class="toc-text">9、使用 Java 的方式配置 Spring</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10%E3%80%81%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F"><span class="toc-number">10.</span> <span class="toc-text">10、代理模式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#10-1%E3%80%81%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86"><span class="toc-number">10.1.</span> <span class="toc-text">10.1、静态代理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#10-2%E3%80%81%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86"><span class="toc-number">10.2.</span> <span class="toc-text">10.2、动态代理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11%E3%80%81AOP"><span class="toc-number">11.</span> <span class="toc-text">11、AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#11-1%E3%80%81%E4%BB%80%E4%B9%88%E6%98%AF-AOP"><span class="toc-number">11.1.</span> <span class="toc-text">11.1、什么是 AOP</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-2%E3%80%81AOP-%E5%9C%A8-Spring-%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-number">11.2.</span> <span class="toc-text">11.2、AOP 在 Spring 的作用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-3%E3%80%81%E4%BD%BF%E7%94%A8-Spring-%E5%AE%9E%E7%8E%B0-AOP"><span class="toc-number">11.3.</span> <span class="toc-text">11.3、使用 Spring 实现 AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%9A%E4%BD%BF%E7%94%A8-Spring-%E6%8E%A5%E5%8F%A3"><span class="toc-number">11.3.1.</span> <span class="toc-text">方法一：使用 Spring 接口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%AE%9E%E7%8E%B0-AOP"><span class="toc-number">11.3.2.</span> <span class="toc-text">方法二：自定义类实现 AOP</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E5%BC%8F%E4%B8%89%EF%BC%9A%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0"><span class="toc-number">11.3.3.</span> <span class="toc-text">方式三：使用注解实现</span></a></li></ol></li></ol></li></ol>
      </div>
    </article>
  
  
  <article class="card card-content categories-widget">
    <div class="categories-card">
  <div class="categories-header">
    <i 
      class="iconfont icon-fenlei" 
      style="padding-right: 2px;">
    </i>分类
  </div>
  <div class="categories-list">
    
      <a href="/categories/Java/">
        <div class="categories-list-item">
          Java
          <span class="categories-list-item-badge">11</span>
        </div>
      </a>
    
      <a href="/categories/SpringBoot/">
        <div class="categories-list-item">
          SpringBoot
          <span class="categories-list-item-badge">16</span>
        </div>
      </a>
    
      <a href="/categories/WPF/">
        <div class="categories-list-item">
          WPF
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/Docker/">
        <div class="categories-list-item">
          Docker
          <span class="categories-list-item-badge">3</span>
        </div>
      </a>
    
      <a href="/categories/Net/">
        <div class="categories-list-item">
          Net
          <span class="categories-list-item-badge">2</span>
        </div>
      </a>
    
      <a href="/categories/DotNetCore/">
        <div class="categories-list-item">
          DotNetCore
          <span class="categories-list-item-badge">2</span>
        </div>
      </a>
    
      <a href="/categories/%E6%8E%92%E5%BA%8F/">
        <div class="categories-list-item">
          排序
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/Redis/">
        <div class="categories-list-item">
          Redis
          <span class="categories-list-item-badge">6</span>
        </div>
      </a>
    
      <a href="/categories/COS/">
        <div class="categories-list-item">
          COS
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/Spring/">
        <div class="categories-list-item">
          Spring
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/IText/">
        <div class="categories-list-item">
          IText
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/GateWay/">
        <div class="categories-list-item">
          GateWay
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/Jenkins/">
        <div class="categories-list-item">
          Jenkins
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/Netty/">
        <div class="categories-list-item">
          Netty
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/Log4j/">
        <div class="categories-list-item">
          Log4j
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
      <a href="/categories/algorithm/">
        <div class="categories-list-item">
          algorithm
          <span class="categories-list-item-badge">1</span>
        </div>
      </a>
    
  </div>
</div>
  </article>
  
  <article class="card card-content tags-widget">
    <div class="tags-card">
  <div class="tags-header">
    <i 
      class="iconfont icon-biaoqian" 
      style="padding-right: 2px;">
    </i>热门标签
  </div>
  <div class="tags-list">
    
      <a 
        href="/tags/SpringBoot/" 
        title="SpringBoot">
        <div class="tags-list-item">SpringBoot</div>
      </a>
    
      <a 
        href="/tags/Spring/" 
        title="Spring">
        <div class="tags-list-item">Spring</div>
      </a>
    
      <a 
        href="/tags/Java/" 
        title="Java">
        <div class="tags-list-item">Java</div>
      </a>
    
      <a 
        href="/tags/Redis/" 
        title="Redis">
        <div class="tags-list-item">Redis</div>
      </a>
    
      <a 
        href="/tags/Docker/" 
        title="Docker">
        <div class="tags-list-item">Docker</div>
      </a>
    
      <a 
        href="/tags/DotNetCore/" 
        title="DotNetCore">
        <div class="tags-list-item">DotNetCore</div>
      </a>
    
      <a 
        href="/tags/IDEA/" 
        title="IDEA">
        <div class="tags-list-item">IDEA</div>
      </a>
    
      <a 
        href="/tags/Maven/" 
        title="Maven">
        <div class="tags-list-item">Maven</div>
      </a>
    
      <a 
        href="/tags/RabbitMQ/" 
        title="RabbitMQ">
        <div class="tags-list-item">RabbitMQ</div>
      </a>
    
      <a 
        href="/tags/Jackson/" 
        title="Jackson">
        <div class="tags-list-item">Jackson</div>
      </a>
    
      <a 
        href="/tags/snowflake/" 
        title="snowflake">
        <div class="tags-list-item">snowflake</div>
      </a>
    
      <a 
        href="/tags/algorithm/" 
        title="algorithm">
        <div class="tags-list-item">algorithm</div>
      </a>
    
      <a 
        href="/tags/Log4j/" 
        title="Log4j">
        <div class="tags-list-item">Log4j</div>
      </a>
    
      <a 
        href="/tags/Socket/" 
        title="Socket">
        <div class="tags-list-item">Socket</div>
      </a>
    
      <a 
        href="/tags/Netty/" 
        title="Netty">
        <div class="tags-list-item">Netty</div>
      </a>
    
      <a 
        href="/tags/Jenkins/" 
        title="Jenkins">
        <div class="tags-list-item">Jenkins</div>
      </a>
    
  </div>
</div>
  </article>
  
  
</div>
            </aside>
            <aside class="right-column">
              <div class="sticky-widescreen">
  
  
    <article class="card card-content toc-card">
      <div class="toc-header">
  <i 
    class="iconfont icon-menu" 
    style="padding-right: 2px;">
  </i>目录
</div>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#1%E3%80%81Spring"><span class="toc-number">1.</span> <span class="toc-text">1、Spring</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2%E3%80%81%E4%BC%98%E7%82%B9"><span class="toc-number">1.1.</span> <span class="toc-text">1.2、优点</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-3%E3%80%81%E7%BB%84%E6%88%90"><span class="toc-number">1.2.</span> <span class="toc-text">1.3、组成</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-4%E3%80%81%E6%8B%93%E5%B1%95"><span class="toc-number">1.3.</span> <span class="toc-text">1.4、拓展</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2%E3%80%81IOC-%E7%90%86%E8%AE%BA%E6%8E%A8%E5%AF%BC"><span class="toc-number">2.</span> <span class="toc-text">2、IOC 理论推导</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#IOC-%E6%9C%AC%E8%B4%A8"><span class="toc-number">2.1.</span> <span class="toc-text">IOC 本质</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3%E3%80%81HelloSpring"><span class="toc-number">3.</span> <span class="toc-text">3、HelloSpring</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4%E3%80%81IOC-%E5%88%9B%E5%BB%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%96%B9%E5%BC%8F"><span class="toc-number">4.</span> <span class="toc-text">4、IOC 创建对象的方式</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5%E3%80%81Spring-%E9%85%8D%E7%BD%AE"><span class="toc-number">5.</span> <span class="toc-text">5、Spring 配置</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1%E3%80%81%E5%88%AB%E5%90%8D"><span class="toc-number">5.1.</span> <span class="toc-text">5.1、别名</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2%E3%80%81Bean-%E7%9A%84%E9%85%8D%E7%BD%AE"><span class="toc-number">5.2.</span> <span class="toc-text">5.2、Bean 的配置</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3%E3%80%81import"><span class="toc-number">5.3.</span> <span class="toc-text">5.3、import</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#6%E3%80%81%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5"><span class="toc-number">6.</span> <span class="toc-text">6、依赖注入</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#6-1%E3%80%81%E6%9E%84%E9%80%A0%E5%99%A8%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.1.</span> <span class="toc-text">6.1、构造器方式注入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-2%E3%80%81Set-%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5%E3%80%90%E9%87%8D%E7%82%B9%E3%80%91"><span class="toc-number">6.2.</span> <span class="toc-text">6.2、Set 方式注入【重点】</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-3%E3%80%81%E6%8B%93%E5%B1%95%E6%96%B9%E5%BC%8F%E6%B3%A8%E5%85%A5"><span class="toc-number">6.3.</span> <span class="toc-text">6.3、拓展方式注入</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#C-%E4%B8%8E-P-%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4"><span class="toc-number">6.4.</span> <span class="toc-text">C 与 P 命名空间</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-4%E3%80%81bean-%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="toc-number">6.5.</span> <span class="toc-text">6.4、bean 的作用域</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#7%E3%80%81Bean-%E7%9A%84%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.</span> <span class="toc-text">7、Bean 的自动装配</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#7-1%E3%80%81ByName-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.1.</span> <span class="toc-text">7.1、ByName 自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-2%E3%80%81ByType-%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.2.</span> <span class="toc-text">7.2、ByType 自动装配</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-3%E3%80%81%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8D"><span class="toc-number">7.3.</span> <span class="toc-text">7.3、使用注解实现自动装配</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#8%E3%80%81%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91"><span class="toc-number">8.</span> <span class="toc-text">8、使用注解开发</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#9%E3%80%81%E4%BD%BF%E7%94%A8-Java-%E7%9A%84%E6%96%B9%E5%BC%8F%E9%85%8D%E7%BD%AE-Spring"><span class="toc-number">9.</span> <span class="toc-text">9、使用 Java 的方式配置 Spring</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#10%E3%80%81%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F"><span class="toc-number">10.</span> <span class="toc-text">10、代理模式</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#10-1%E3%80%81%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86"><span class="toc-number">10.1.</span> <span class="toc-text">10.1、静态代理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#10-2%E3%80%81%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86"><span class="toc-number">10.2.</span> <span class="toc-text">10.2、动态代理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#11%E3%80%81AOP"><span class="toc-number">11.</span> <span class="toc-text">11、AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#11-1%E3%80%81%E4%BB%80%E4%B9%88%E6%98%AF-AOP"><span class="toc-number">11.1.</span> <span class="toc-text">11.1、什么是 AOP</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-2%E3%80%81AOP-%E5%9C%A8-Spring-%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="toc-number">11.2.</span> <span class="toc-text">11.2、AOP 在 Spring 的作用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-3%E3%80%81%E4%BD%BF%E7%94%A8-Spring-%E5%AE%9E%E7%8E%B0-AOP"><span class="toc-number">11.3.</span> <span class="toc-text">11.3、使用 Spring 实现 AOP</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%9A%E4%BD%BF%E7%94%A8-Spring-%E6%8E%A5%E5%8F%A3"><span class="toc-number">11.3.1.</span> <span class="toc-text">方法一：使用 Spring 接口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%AE%9E%E7%8E%B0-AOP"><span class="toc-number">11.3.2.</span> <span class="toc-text">方法二：自定义类实现 AOP</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%96%B9%E5%BC%8F%E4%B8%89%EF%BC%9A%E4%BD%BF%E7%94%A8%E6%B3%A8%E8%A7%A3%E5%AE%9E%E7%8E%B0"><span class="toc-number">11.3.3.</span> <span class="toc-text">方式三：使用注解实现</span></a></li></ol></li></ol></li></ol>
    </article>
  
  
  <article class="card card-content">
    <div class="recent-posts-card">
  <div class="recent-posts-header">
    <i 
      class="iconfont icon-wenzhang_huaban" 
      style="padding-right: 2px;">
    </i>最近文章
  </div>
  <div class="recent-posts-list">
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2022-07-08</div>
        <a href="/2022/07/08/SpringBoot-RabbitMQ%E5%BA%94%E7%94%A8/"><div class="recent-posts-item-content">SpringBoot-RabbitMQ应用</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2022-03-26</div>
        <a href="/2022/03/26/IDEA%E9%83%A8%E7%BD%B2Docker%E9%A0%85%E7%9B%AE/"><div class="recent-posts-item-content">IDEA部署Docker項目</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2022-03-04</div>
        <a href="/2022/03/04/%E5%9F%BA%E4%BA%8EJackson%E7%9A%84JsonFilter%E5%AE%9E%E7%8E%B0%E5%8A%A8%E6%80%81%E6%95%B0%E6%8D%AE%E5%A1%AB%E5%86%99/"><div class="recent-posts-item-content">基于Jackson的JsonFilter实现动态数据填写</div></a>
      </div>
    
      <div class="recent-posts-item">
        <div class="recent-posts-item-title">2022-02-16</div>
        <a href="/2022/02/16/SpringBoot-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%B3%A8%E8%A7%A3%E5%8D%95%E5%8F%82%E6%95%B0Post/"><div class="recent-posts-item-content">SpringBoot-自定义注解单参数Post</div></a>
      </div>
    
  </div>
</div>
  </article>
  
  
</div>
            </aside>
          </div>
        </div>
      </div>
    </div>
     
    <footer class="footer">
  <div class="footer-container">
    <div>
      <div class="footer-dsc">
        <span>
          Copyright ©
          
            2020 -
          
          2022
        </span>
        &nbsp;
        <a 
          href="/" 
          class="footer-link">
          Gas
        </a>
      </div>
    </div>

    
      <div class="footer-dsc">
        
          Powered by
          <a 
            href="https://hexo.io/" 
            class="footer-link" 
            target="_blank" 
            rel="nofollow noopener noreferrer">
            &nbsp;Hexo
          </a>
        
        
          <span>&nbsp;|&nbsp;</span>
        
        
          Theme -
          <a 
            href="https://github.com/theme-kaze" 
            class="footer-link" 
            target="_blank"
            rel="nofollow noopener noreferrer">
            &nbsp;Kaze
          </a>
        
      </div>
    
    
    
    
      <div class="footer-dsc">
        
          本站总访问量<span id="busuanzi_value_site_pv"></span>次
        
        
          <span>&nbsp;|&nbsp;</span>
        
        
          本站总访客数<span id="busuanzi_value_site_uv"></span>次
        
      </div>
      
    
</footer> 
    
  <a 
    role="button" 
    id="scrollbutton" 
    class="basebutton" 
    aria-label="回到顶部">
    <i class="iconfont icon-arrowleft button-icon"></i>
  </a>

<a 
  role="button" 
  id="menubutton" 
  class="basebutton">
  <i class="iconfont icon-menu button-icon"></i>
</a>
<a 
  role="button" 
  id="popbutton" 
  class="basebutton" 
  aria-label="控制中心">
  <i class="iconfont icon-expand button-icon"></i>
</a>
<a 
  role="button" 
  id="darkbutton" 
  class="basebutton darkwidget" 
  aria-label="夜色模式">
  <i class="iconfont icon-weather button-icon"></i>
</a>
<a 
  role="button" 
  id="searchbutton" 
  class="basebutton searchwidget" 
  aria-label="搜索">
  <i class="iconfont icon-search button-icon"></i>
</a> 
     
     
     
      <script>
  var addImgLayout = function () {
    var img = document.querySelectorAll('.post-content img')
    var i
    for (i = 0; i < img.length; i++) {
      var wrapper = document.createElement('a')
      wrapper.setAttribute('href', img[i].getAttribute('data-src'))
      wrapper.setAttribute('aria-label', 'illustration')
      wrapper.style.cssText =
        'width: 100%; display: flex; justify-content: center;'
      if (img[i].alt) wrapper.dataset.caption = img[i].alt
      wrapper.dataset.nolink = true
      img[i].before(wrapper)
      wrapper.append(img[i])
      var divWrap = document.createElement('div')
      divWrap.classList.add('gallery')
      wrapper.before(divWrap)
      divWrap.append(wrapper)
    }
    baguetteBox.run('.gallery')
  }
</script>
<script>
  loadScript(
    "/js/lib/lightbox/baguetteBox.min.js",
    addImgLayout
  )
</script>
 
     
     
    <script src="/js/main.js"></script> 
    
      <script> 
        loadScript('/js/lib/busuanzi.min.js') 
      </script>
     
    
      <script>
        var addLazyload = function () {
          var observer = lozad('.lozad', {
            load: function (el) {
              el.srcset = el.getAttribute('data-src')
            },
            loaded: function (el) {
              el.classList.add('loaded')
            },
          })
          observer.observe()
        }
      </script>
      <script>
        loadScript('/js/lib/lozad.min.js', addLazyload)
      </script>
     
    
    
      <script>
        setTimeout(() => {localSearch("search.json")}, 0)
      </script>
    
  </body>
</html>
